﻿#include "tcpfilepost.h"
#include <QtNetwork>

tcpFilePost::tcpFilePost()
{
    m_payloadSize=64*1024;
    m_totalBytes=0;
    m_bytesWritten=0;
    m_bytesToWrite=0;
    m_tcpClient=new QTcpSocket();

    connect(m_tcpClient,SIGNAL(connected()),this,SLOT(startTransfer()));
    connect(m_tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updateClientProgress(qint64)));
    connect(m_tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(displayError(QAbstractSocket::SocketError)));

}

void tcpFilePost::send(QString ip_address,QString port,QString filename)
{
    m_fileName = filename;
    m_bytesWritten = 0;
    m_tcpClient->connectToHost(ip_address,port.toInt());
}

void tcpFilePost::startTransfer()
{
    m_localFile=new QFile(m_fileName);
    if(!m_localFile->open(QFile::ReadOnly)){
       qDebug()<<"client：open file error!";
       return;
    }
    m_totalBytes=m_localFile->size();

    // 构造一个便于操作字节序列 m_outBlock 的数据流 sendOut
    QDataStream sendOut(&m_outBlock,QIODevice::WriteOnly);
    sendOut.setVersion(QDataStream::Qt_5_7);

    // 把文件名存入字节序列 m_outBlock
    QString currentFileName=m_fileName.right(m_fileName.size()-m_fileName.lastIndexOf('/')-1);
    sendOut<<qint64(0)<<qint64(0)<<currentFileName;

    // 获得文件+文件名的总字节数
    m_totalBytes+=m_outBlock.size();

    // 重定位数据流写入位置
    sendOut.device()->seek(0);
    sendOut<<m_totalBytes<<qint64(m_outBlock.size()-sizeof(qint64)*2);

    m_bytesToWrite=m_totalBytes-m_tcpClient->write(m_outBlock);
    m_outBlock.resize(0);
}

void tcpFilePost::updateClientProgress(qint64 numBytes)
{
    m_bytesWritten+=(int)numBytes;
    if(m_bytesToWrite>0){
        m_outBlock=m_localFile->read(qMin(m_bytesToWrite,m_payloadSize));
        m_bytesToWrite-=(int)m_tcpClient->write(m_outBlock);
        m_outBlock.resize(0);
    }
    else{
        m_localFile->close();
    }

    if(m_bytesWritten!=m_totalBytes)
    {
        emit sig_PostProgress(m_bytesWritten*100/m_totalBytes);
    }else{
        m_localFile->close();
        m_tcpClient->close();
        emit sig_PostProgress(100);
    }
}

void tcpFilePost::displayError(QAbstractSocket::SocketError)
{
    qDebug()<<m_tcpClient->errorString();
    m_tcpClient->close();

    emit sig_PostError(m_tcpClient->errorString());
}
